package com.fingard.dsp.bank.directbank.nbcb01;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.diagnostics.LogHelper;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.net.ITcpClient;
import com.fingard.net.TcpPortClient;
import com.fingard.net.TcpReceiver;
import com.fingard.net.WebRequest;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;


public class NBCB01Base extends DirectBase implements ITcpClient {
    protected String serviceId = "";
    private static String softwareId = "";
    protected String signature = "";
    protected String[] tmpSign = new String[]{"", ""};

    private static Object lockMutex = new Object();

    protected String getBnkToken() {
        synchronized (lockMutex) {
            if (StringHelper.isNullOrEmpty(softwareId)) {
                softwareId = getBankConfig().getValueAsString("softwareId");
            } else {
                softwareId = "201";
            }
            boolean isLoginValid = false;
            if (StringHelper.isNullOrEmpty(bankFront.token)) {
                isLoginValid = true;
            } else if (bankFront.lastVisitTime == null) {
                isLoginValid = true;
            } else {
                int timeOut = getBankConfig().getValueAsInt("sessionMins");
                timeOut = timeOut <= 0 ? 10 : timeOut;
                Date currDate = new Date();
                if (DateHelper.getDifferMins(currDate, bankFront.lastVisitTime) > timeOut) {
                    isLoginValid = true;
                } else if (DateHelper.compareDay(currDate, bankFront.lastVisitTime) != 0) {
                    isLoginValid = true;
                }
            }
            if (getBankConfig().getValueAsBool("needLogin")) {
                if (isLoginValid) {
                    WriteBankLogLn("当前未登录前置，现在进行登录");
                    login();
                }
            }
            return bankFront.token;
        }
    }

    protected void login() {
        try {
            int tmpMaxFailCount = getBankConfig().getValueAsInt("maxLoginFail");
            if (bankFront.loginFailCount >= tmpMaxFailCount) {
                WriteBankLogLn("登录失败次数" + bankFront.loginFailCount + "已达到上限，不再进行登录");
                return;
            }
            Date date = new Date();
            bankFront.lastLoginTime = date;
            bankFront.token = "";
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            //写入通用的头部节点
            xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            xmlWriter.writeStartElement("NBCBEBankData");
            xmlWriter.writeElementString("sessionId", "-1");
            xmlWriter.writeElementString("serviceId", "srv001_signOn");//服务编号
            xmlWriter.writeElementString("customerId", bankFront.loginName);
            xmlWriter.writeElementString("softwareId", getBankConfig().getValueAsString("softwareId"));
            xmlWriter.writeElementString("functionId", "srv001");
            xmlWriter.writeElementString("functionName", "登录");
            xmlWriter.writeStartElement("opReq");
            xmlWriter.writeElementString("serialNo", Format.Time12Format.format(date));
            xmlWriter.writeElementString("reqTime", Format.DateTime14Format.format(bankFront.lastLoginTime));
            xmlWriter.writeStartElement("ReqParam");
            xmlWriter.writeElementString("userID", bankFront.loginName);
            xmlWriter.writeElementString("userPWD", bankFront.loginPasswd);
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            String signXml = getDataSignData(xmlWriter);
            if (signnatrue(signXml) == true) {

            }
            xmlWriter.writeElementString("signData", signature);
            xmlWriter.writeEndDocument();
            String[] tmpStrRet = sendToBank(getDataSendBank(xmlWriter.toXmlString()));
            //模拟登录成功
            /*bankFront.token = "1234";*/
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();

                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

                if (tmpBkReader != null) {
                    String tmprspcod = tmpBkReader.getFirstText("/NBCBEBankData/retCode");
                    String tmprspmsg = tmpBkReader.getFirstText("/NBCBEBankData/errorMsg");
                    if (tmprspcod != null && isActiveRetCode(tmprspcod)) {
                        bankFront.token = tmpBkReader.getFirstText("/NBCBEBankData/sessionId");
                        bankFront.loginFailCount = 0;
                        WriteBankLogLn("登录成功");
                    } else {
                        bankFront.loginFailCount = bankFront.loginFailCount + 1;
                        WriteBankLogLn("登录失败：" + tmprspmsg);
                    }
                } else {
                    WriteBankLogLn("登录失败");
                }
            } else {
                WriteBankLogLn("登录失败：" + tmpStrRet[1]);
            }
        } catch (Exception e) {
            WriteBankLogLn("登录异常：" + LogHelper.getStackTrace(e));
            e.printStackTrace();
        }
    }

    protected String getQryTransID() {
        Date tmpDateNow = new Date();
        return Format.DateTime17SSSFormat.format(tmpDateNow);
    }

    protected String getCharset() {
        return getBankConfig().getCharset("GBK");
    }

    protected String getSignCharset() {
        return getBankConfig().getValueAsString("signCharset");
    }


    protected void writeCommonHeader(XmlTextWriter xmlWriter) throws Exception {
        if (StringHelper.isNullOrEmpty(serviceId)) {
            throw new Exception("未赋值serviceId");
        }
        //写入通用的头部节点
        xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        xmlWriter.writeStartElement("NBCBEBankData");
        xmlWriter.writeElementString("sessionId", getBnkToken());
        xmlWriter.writeElementString("serviceId", serviceId);//服务编号
        xmlWriter.writeElementString("customerId", bankFront.loginName);
        xmlWriter.writeElementString("softwareId", getBankConfig().getValueAsString("softwareId"));
    }

    protected String[] sendToBank(String p_reqStr) throws Exception {
        String[] retStr = new String[]{"", ""};

        WriteBankLogLn("1.提交银行的地址：" + bankFront.serverURL);
        WriteBankLogStep2(p_reqStr);

        WebRequest tmpWebRequest = new WebRequest(bankFront.serverURL);
        tmpWebRequest.setConnectTimeout(60000);
        tmpWebRequest.setRequestProperty("Content-Type", "application/xml");
        tmpWebRequest.setRequestProperty("connection", "Close");
        String charsetName = getCharset();
        byte[] tmpToWriteBytes = p_reqStr.getBytes(charsetName);
        retStr = tmpWebRequest.upload(tmpToWriteBytes, charsetName);
        WriteBankLogStep3(retStr[1]);

        return retStr;
    }

    protected boolean isActiveRetCode(String retCode) {
        if (retCode != null) {
            if (retCode.equals("20000")) {
                bankFront.token = "";//需要重新登录
            }
            if (retCode.equals("0000")) {
                bankFront.lastVisitTime = new Date();
                return true;
            }
        }
        return false;
    }

    //处理数据签名
    protected Boolean signnatrue(String signXml) throws Exception {
        WriteBankLogLn("1.银行签名地址:" + bankFront.serverIP + ":" + bankFront.signPort);

        //发送银行前置
        try {
            TcpPortClient tmpClient = new TcpPortClient(bankFront.serverIP, Integer.parseInt(bankFront.signPort), this);

            String tmpCharset = getSignCharset();
            int length = signXml.getBytes("GB2312").length;
            signXml = "<?xml version=1.0 encoding=\"gb2312\"?><msg><msg_head><msg_type>0</msg_type><msg_id>1005</msg_id><msg_sn>0</msg_sn><version>1</version></msg_head><msg_body><origin_data_len>" + length + "</origin_data_len><origin_data>" + signXml + "</origin_data></msg_body></msg>";
            String p_reqString = signXml;
            /*System.out.println("转换签名后数据" + p_reqString);*/
            byte[] tmpBytesBody = p_reqString.getBytes(tmpCharset);
            WriteBankLogLn("2.发送银行进行签名的数据:" + p_reqString);
            TcpReceiver tmpReceiver = tmpClient.sendMessage(tmpBytesBody);
            tmpSign[0] = tmpReceiver.connState;
            if (tmpReceiver.recBytes != null) {
                tmpSign[1] = new String(tmpReceiver.recBytes, 0, tmpReceiver.readedLength, tmpCharset);
                WriteBankLogLn("3.签名返回的结果" + tmpSign[1]);
            } else {
                tmpSign[1] = tmpReceiver.getConnMsg();
            }
            if (!tmpReceiver.isCompleted) {
                WriteBankLogLn(tmpReceiver.getConnMsg());
            }
            if (tmpSign[0].length() == 0) {
                WriteBankLogLn("签名成功");
                signature = tmpSign[1].substring(tmpSign[1].indexOf("<signed_data>") + 13, tmpSign[1].indexOf("</signed_data>")).replace("\r", "").replace("\n", "");
                return true;
            } else {
                WriteBankLogLn("签名失败");
                return false;
            }
        } catch (Exception e) {
            WriteBankLogLn("与银行签名端口通讯失败；详细信息：" + tmpSign[1]);
        }
        return false;
    }

    @Override
    public void getContentLength(TcpReceiver p_receiver) throws Exception {
        if (p_receiver.contentLength == -1) {
            String tmpCharset = getCharset();
            String tmpRecNow = new String(p_receiver.recBytes, 0, p_receiver.readedLength, tmpCharset);
            if (tmpRecNow.indexOf("</NBCBEBankData>") >= 0) {
                p_receiver.contentLength = p_receiver.readedLength;
                p_receiver.contentStartIndex = 0;
            }
        }
    }

    public String clearWarpAndBlank(String data) {
        return data.replace("\r", "").replace("\n", "").replace(" ", "");
    }

    public String getDataSignData(XmlTextWriter xmlTextWriter) {
        String data = xmlTextWriter.toXmlString();
        return clearWarpAndBlank(data.substring(data.indexOf("<opReq>"), data.indexOf("</opReq>") + 8));
    }

    public String getDataSendBank(String bankData) {
        String data = bankData.substring(0, bankData.indexOf("<opReq>")) + clearWarpAndBlank(bankData.substring(bankData.indexOf("<opReq>"), bankData.indexOf("</opReq>") + 8)) + bankData.substring(bankData.indexOf("</opReq>") + 8);
        return data;
    }

    //上送格式为json格式
    protected String[] sendToATS(String jsonData) throws Exception {
        String[] retStr = new String[]{"", ""};
        WriteBankLogLn("2.提交ATS的地址：" + FGBiz.dspCenter.dspSet.receiptPushServerUrl);


        //发送银行前置
        WebRequest tmpRequest = new WebRequest(FGBiz.dspCenter.dspSet.receiptPushServerUrl);
        tmpRequest.setConnectTimeout(60000);
        tmpRequest.setRequestProperty("connection", "Close");
        tmpRequest.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        String charsetName = "gbk";
        WriteBankLogLn("3.推送给ATS的json数据" + jsonData);
        byte[] tmpWriteBytes = jsonData.getBytes(charsetName);
        retStr = tmpRequest.upload(tmpWriteBytes, charsetName);
        WriteBankLogLn("4.返回的数据" + retStr[1]);

        return retStr;
    }

    /**
     * 根据票据号码查询票据明细
     * @param billNo 票据号码
     * @return
     * @throws Exception
     *//*
	protected String queryBillDetails(String seqNo,String billNo) throws Exception{
		if ("".equals(billNo) || billNo==null){
			return null;
		}
		if ("".equals(seqNo) || seqNo==null){
			return null;
		}
		serviceId = "srv173_singleBillInfoQuery";
		XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
		writeCommonHeader(xmlWriter);
		xmlWriter.writeElementString("functionId", "srv173");
		xmlWriter.writeElementString("functionName", "单笔票据查询");
		xmlWriter.writeStartElement("opReq");
		xmlWriter.writeElementString("serialNo", seqNo);//交易序列号
		xmlWriter.writeElementString("reqTime", Format.Date8Format.format(new Date()));//客户端请求时间
		xmlWriter.writeStartElement("ReqParam");
		xmlWriter.writeElementString("PJHM", billNo.trim());//票据号码
		xmlWriter.writeEndElement();
		xmlWriter.writeEndElement();
		String signXml = getDataSignData(xmlWriter);
		if (signnatrue(signXml) == true) {
			xmlWriter.writeElementString("signData", signature);//签名数据
			xmlWriter.writeEndDocument();
			String[] tmpStrRet = sendToBank(getDataSendBank(xmlWriter.toXmlString()));//发送银行
			if (tmpStrRet[0].length() == 0) {
				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
				if (tmpBkReader != null) {
					String respCode = tmpBkReader.getFirstText("/NBCBEBankData/retCode");
					if (respCode != null && isActiveRetCode(respCode)) {
						return tmpStrRet[1];
					}
				}
			}
		}
		return null;
	}*/

    /**
     * 查询账户基本信息获取开户网点
     *
     * @param
     * @return
     * @throws Exception
     */
    protected String getTransferNode(String act) throws Exception {
        String accountNo = "";
        if ("".equals(act) || act == null) {
            return null;
        }
        serviceId = "srv003_singleAccountInfoQuery";
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        writeCommonHeader(xmlWriter);
        xmlWriter.writeElementString("functionId", "srv003");
        xmlWriter.writeElementString("functionName", "账户余额查询");
        xmlWriter.writeStartElement("opReq");
        xmlWriter.writeElementString("serialNo", getQryTransID());//交易序列号
        xmlWriter.writeElementString("reqTime", Format.DateTime14Format.format(new Date()));//客户端请求时间
        xmlWriter.writeStartElement("ReqParam");
        xmlWriter.writeElementString("ZHHA", act);
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        String signXml = getDataSignData(xmlWriter);
        if (signnatrue(signXml) == true) {
            xmlWriter.writeElementString("signData", signature);//签名数据
            xmlWriter.writeEndDocument();
            String[] tmpStrRet = sendToBank(getDataSendBank(xmlWriter.toXmlString()));//发送银行
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String respCode = tmpBkReader.getFirstText("/NBCBEBankData/retCode");
                    if (respCode != null && isActiveRetCode(respCode)) {
                        while (tmpBkReader.read("/NBCBEBankData/opRep/opResult")) {
                            accountNo = tmpBkReader.readedXElement.getSingleTextNotNull("KHWD");//开户网点
                        }
                    }
                }
            }
        }
        return accountNo;
    }

    /**
     * 新开保证金
     *
     * @param
     * @return
     * @throws Exception
     */
    protected String[] newMarginAccount(String money, String act) throws Exception {
        String[] accountNo = new String[]{"", ""};
        if ("".equals(money) || money == null) {
            return null;
        }
        if ("".equals(act) || act == null) {
            return null;
        }
        serviceId = "srv022_marginAccOpen";
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        writeCommonHeader(xmlWriter);
        xmlWriter.writeElementString("functionId", "srv022");
        xmlWriter.writeElementString("functionName", "新开保证金");
        xmlWriter.writeStartElement("opReq");
        xmlWriter.writeElementString("serialNo", getQryTransID());//交易序列号
        xmlWriter.writeElementString("reqTime", Format.Date8Format.format(new Date()));//客户端请求时间
        xmlWriter.writeStartElement("ReqParam");
        xmlWriter.writeElementString("businessType", "0");//业务类型
        xmlWriter.writeElementString("payAccount", act);//付款账户
        xmlWriter.writeElementString("currencyType", "01");//币种
        xmlWriter.writeElementString("transferAmt", money);//金额
        xmlWriter.writeElementString("transferNode", getTransferNode(act));//办理网点
        xmlWriter.writeElementString("kindFlag", "");//定活标识
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        String signXml = getDataSignData(xmlWriter);
        if (signnatrue(signXml) == true) {
            xmlWriter.writeElementString("signData", signature);//签名数据
            xmlWriter.writeEndDocument();
            String[] tmpStrRet = sendToBank(getDataSendBank(xmlWriter.toXmlString()));//发送银行
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String respCode = tmpBkReader.getFirstText("/NBCBEBankData/retCode");
                    if (respCode != null && isActiveRetCode(respCode)) {
                        if (tmpBkReader.read("/NBCBEBankData/opRep/list/row")) {
                            accountNo[0] = tmpBkReader.readedXElement.getSingleTextNotNull("accountNo");//保证金账号
                            accountNo[1] = tmpBkReader.readedXElement.getSingleTextNotNull("subAccountNo");//保证金子账号
                        }
                    }
                }
            }
        }
        return accountNo;
    }

    /**
     * 保证金过度户查询
     *
     * @param
     * @return
     * @throws Exception
     */
    protected String[] getMarginAccount(String drawCode, String drawType) throws Exception {
        String[] accountNo = new String[]{"", ""};
        if ("".equals(drawCode) || drawCode == null) {
            return null;
        }
        if ("".equals(drawType) || drawType == null) {
            return null;
        }
        serviceId = "srv184_queryMarginAccount";
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        writeCommonHeader(xmlWriter);
        xmlWriter.writeElementString("functionId", "srv184");
        xmlWriter.writeElementString("functionName", "保证金过渡户查询");
        xmlWriter.writeStartElement("opReq");
        xmlWriter.writeElementString("serialNo", getQryTransID());//交易序列号
        xmlWriter.writeElementString("reqTime", Format.Date8Format.format(new Date()));//客户端请求时间
        xmlWriter.writeStartElement("ReqParam");
        xmlWriter.writeElementString("BZJLX", "0");//保证金类型
        xmlWriter.writeElementString("BIZH", "01");//币种
        xmlWriter.writeElementString("ZJHM", drawType);//证件号码
        xmlWriter.writeElementString("ZJLX", drawCode);//证件类型 6组织机构代码
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        String signXml = getDataSignData(xmlWriter);
        if (signnatrue(signXml) == true) {
            xmlWriter.writeElementString("signData", signature);//签名数据
            xmlWriter.writeEndDocument();
            String[] tmpStrRet = sendToBank(getDataSendBank(xmlWriter.toXmlString()));//发送银行
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String respCode = tmpBkReader.getFirstText("/NBCBEBankData/retCode");
                    if (respCode != null && isActiveRetCode(respCode)) {
                        if (tmpBkReader.read("/NBCBEBankData/opRep/opResult/list/row")) {
                            accountNo[0] = tmpBkReader.readedXElement.getSingleTextNotNull("ZHHA");//保证金账号
                            accountNo[1] = tmpBkReader.readedXElement.getSingleTextNotNull("ZZH");//保证金子账号
                        }
                    }
                }
            }
        } else {
            throw new Exception("签名失败！");
        }
        return accountNo;
    }

    /**
     * 签收类
     */
    protected String getBillTypeIsB003(String billType, String overdueFlag) throws Exception {
        String eBillBusessType = "";
        switch (Integer.valueOf(billType)) {
            //应答类型 1-承兑应答 2-收票应答 3-背书转让应答 4-回购式贴现赎回应答 5-质押解除应答 6-提示付款应答 7-保证应答 8-同意清偿应,9-质押签收
            case 1:
                throw new Exception("银行不支持承兑签收票据查询");//承兑
            case 2:
                eBillBusessType = "1";
                break;//提示收票
            case 3:
                eBillBusessType = "2";
                break;//背书转让
            case 4:
                throw new Exception("银行不支持回购式贴现赎回签收票据查询");//回购式贴现赎回
            case 5:
                eBillBusessType = "7";
                break;//解质押
            case 6:
                if ("1".equals(overdueFlag)) {
                    eBillBusessType = "8";
                } else {
                    eBillBusessType = "9";
                }
                break;//提示付款
            case 7:
                eBillBusessType = "5";
                break;//背书保证
            case 8:
                throw new Exception("银行不支持清偿签收票据查询");//同意清偿
            case 9:
                eBillBusessType = "6";
                break;//质押
            default:
                throw new Exception("未知的申请操作类型");
        }
        return eBillBusessType;
    }

	/**查询类*/
	protected String getBillType(String billType,String overdueFlag) throws Exception{
		String eBillBusessType="";
		switch (Integer.valueOf(billType)){
			//1-出票 2-承兑 3-收票 4-背书转让 5-质押 6-解质押 7-出票保证 8-承兑保证 9-背书保证 10-贴现 11-回购式贴现赎回 12-提示付款 13-追索 14-同意清偿
			case 1:throw new Exception("银行不支持出票的可操作票据查询");//出票
			case 2:throw new Exception("银行不支持承兑的可操作票据查询");//承兑
			case 3:eBillBusessType = "1";break;//提示收票
			case 4:eBillBusessType = "2";break;//背书转让
			case 5:eBillBusessType = "6";break;//质押
			case 6:eBillBusessType = "7";break;//解质押
			case 7:eBillBusessType = "3";break;//出票保证
			case 8:eBillBusessType = "4";break;//承兑保证
			case 9:eBillBusessType = "5";break;//背书保证
			case 10:throw new Exception("银行不支持贴现的可操作票据查询");//贴现
			case 11:throw new Exception("银行不支持回购式贴现赎回的可操作票据查询");//回购式贴现赎回
			case 12:
				if ("1".equals(overdueFlag)) {
					eBillBusessType = "8";
				} else if ("2".equals(overdueFlag)) {
					eBillBusessType = "9";
				}
				break;//提示付款
			case 13:throw new Exception("银行不支持追索的可操作票据查询");//追索
			case 14:throw new Exception("银行不支持清偿的可操作票据查询");//同意清偿
			default:throw new Exception("未知的申请操作类型");
		}
		return eBillBusessType;
	}

    /**
     * 计算期限
     *
     * @param startDate
     * @param endDate
     * @return
     * @throws Exception
     */
    protected static int timeDifference(String startDate, String endDate) throws Exception {
        startDate = startDate.substring(0, 10);
        endDate = endDate.substring(0, 10);
        Calendar bef = Calendar.getInstance();
        bef.setTime(Format.Date10Format.parse(startDate));
        Calendar aft = Calendar.getInstance();
        aft.setTime(Format.Date10Format.parse(endDate));
        int result = aft.get(Calendar.MONTH) - bef.get(Calendar.MONTH);
        int month = (aft.get(Calendar.YEAR) - bef.get(Calendar.YEAR)) * 12;
        return Math.abs(month + result);
    }

	/**
	 * 票据类型映射
	 * @param billType
	 * @return
	 */
	protected String getBillTypeToBank(String billType){
		return "1".equals(billType) ? "107" : ("2".equals(billType) ? "108":"");
	}

	/**
	 * 票据类型映射
	 * @param billType
	 * @return
	 */
	protected String getBillTypeToAts(String billType){
		return "107".equals(billType) ? "1" : ("108".equals(billType) ? "2":"");
	}

	/**
	 * 查询持票类、待签收 票据信息 申请ok 签收？
	 * @param actNum
	 * @param billType
	 * @param billNo
	 * @param queryType
	 * @param playType 操作类型 1可申请 2待签收
	 * @return
	 */
	protected XElement getBillInfoByOwn(String actNum, String billType, String billNo, String queryType, String playType)throws Exception {
		//赋值通用参数
		if("1".equals(playType)){
			serviceId = "srv3004_applyCommonQuery";
		}else if("2".equals(playType)){
			serviceId = "srv3005_signCommonQuery";
		}
		XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
		//写入通用的头部节点
		writeCommonHeader(xmlWriter);
		if (!"".equals(bankFront.token)) {
			//查询条件转换
            if("1".equals(playType)){
                xmlWriter.writeElementString("functionId", "srv3004");
                xmlWriter.writeElementString("functionName", "通用申请查询");
            }else if("2".equals(playType)){
                xmlWriter.writeElementString("functionId", "srv3005");
                xmlWriter.writeElementString("functionName", "通用签收查询");
            }
			//请求报文体
			xmlWriter.writeStartElement("opReq");
			xmlWriter.writeElementString("serialNo", getQryTransID());//交易序列号
			xmlWriter.writeElementString("reqTime", Format.Date8Format.format(new Date()));//客户端请求时间
			xmlWriter.writeStartElement("ReqParam");
			xmlWriter.writeElementString("KHHM", getBankConfig().getValueAsString("customerID"));//实际交易客户号
			xmlWriter.writeElementString("SQQR", "");//开始时间
			xmlWriter.writeElementString("SQZR", "");//结束时间
			xmlWriter.writeElementString("XSYH", "1");//页号
			xmlWriter.writeElementString("XSTS", getBankConfig().getValueAsString("pageSize"));//每页数量
			xmlWriter.writeElementString("CXTJ", queryType);//查询条件
			xmlWriter.writeElementString("ZH", actNum);//出票账号
			xmlWriter.writeElementString("ZZH", "");//子账号
			xmlWriter.writeElementString("PJHM", billNo);//票据号码
			xmlWriter.writeElementString("PJZL", getBillTypeToBank(billType));//票据类型
			xmlWriter.writeEndElement();
			xmlWriter.writeEndElement();
			String signXml = getDataSignData(xmlWriter);
			if (signnatrue(signXml) == true) {
				xmlWriter.writeElementString("signData", signature);//签名数据
				xmlWriter.writeEndDocument();
				String[] tmpStrRet = sendToBank(getDataSendBank(xmlWriter.toXmlString()));//发送银行
				if (tmpStrRet[0].length() == 0) {
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
					if (tmpBkReader != null) {
						String respCode = tmpBkReader.getFirstText("/NBCBEBankData/retCode");
						String respInfo = tmpBkReader.getFirstText("/NBCBEBankData/errorMsg");
						if (respCode != null && isActiveRetCode(respCode)) {
						    int totalCount = Integer.parseInt(tmpBkReader.getFirstText("/NBCBEBankData/opRep/opResult/totalNumber"));
                            if (totalCount!=1) {
                                throw new Exception("返回的数据不唯一！");
                            }
							if (tmpBkReader.read("/NBCBEBankData/opRep/opResult/list/row")) {
								return tmpBkReader.readedXElement;
							}
						} else {
							throw new Exception(respInfo);
						}
					} else {
						throw new Exception(tmpSbMsg.toString());
					}
				} else {
					throw new Exception(tmpStrRet[1]);
				}
			} else {
				throw new Exception(tmpSign[1]);
			}
		} else {
			throw new Exception("登录失败");
		}
		return null;
	}

	/**
	 * 查询开票类的票据信息
	 * @param actNum
	 * @param billType
	 * @param billNo
	 * @param queryType
	 * @return
	 * @throws Exception
	 */
	protected XElement getBillInfoByOpen(String actNum,String billType,String billNo, String queryType)throws Exception   {
		//赋值通用参数
		serviceId = "srv183_bankTicketInfoQuery";
		XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
		//写入通用的头部节点
		writeCommonHeader(xmlWriter);
		if (!"".equals(bankFront.token)) {
			xmlWriter.writeElementString("functionId", "srv183");
			xmlWriter.writeElementString("functionName", "出票信息查询");
			//请求报文体
			xmlWriter.writeStartElement("opReq");
			xmlWriter.writeElementString("serialNo", getQryTransID());//交易序列号
			xmlWriter.writeElementString("reqTime", Format.Date8Format.format(new Date()));//客户端请求时间
			xmlWriter.writeStartElement("ReqParam");
			xmlWriter.writeElementString("KHHM", getBankConfig().getValueAsString("customerID"));//实际交易客户号
			String billIssDate = Format.Date8Format.format(Format.Date8Format.parse(billNo.substring(13,21)));
			xmlWriter.writeElementString("CPQR", billIssDate);//开始时间
			xmlWriter.writeElementString("CPZR", billIssDate);//结束时间
			xmlWriter.writeElementString("CXTJ", queryType);//查询条件
			xmlWriter.writeElementString("ZH", actNum);//出票账号
			xmlWriter.writeElementString("FZH", "");//子账号
			xmlWriter.writeElementString("CZH", "");//出账号
			xmlWriter.writeElementString("PJHM", billNo);//票据号码
			xmlWriter.writeElementString("PJZL", getBillTypeToBank(billType));//票据类型
			xmlWriter.writeElementString("XSYH", "1");//页号
			xmlWriter.writeElementString("XSTS", getBankConfig().getValueAsString("pageSize"));//每页数量
			xmlWriter.writeEndElement();
			xmlWriter.writeEndElement();
			String signXml = getDataSignData(xmlWriter);
			if (signnatrue(signXml) == true) {
				xmlWriter.writeElementString("signData", signature);//签名数据
				xmlWriter.writeEndDocument();
				String[] tmpStrRet = sendToBank(getDataSendBank(xmlWriter.toXmlString()));//发送银行
				if (tmpStrRet[0].length() == 0) {
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
					if (tmpBkReader != null) {
						String respCode = tmpBkReader.getFirstText("/NBCBEBankData/retCode");
						String respInfo = tmpBkReader.getFirstText("/NBCBEBankData/errorMsg");
						if (respCode != null && isActiveRetCode(respCode)) {
                            int totalCount = Integer.parseInt(tmpBkReader.getFirstText("/NBCBEBankData/opRep/opResult/totalNumber"));
							//获取总记录数
                            if (totalCount!=1) {
                                throw new Exception("返回的数据不唯一！");
                            }
							while (tmpBkReader.read("/NBCBEBankData/opRep/opResult/list/row")) {
								return tmpBkReader.readedXElement;
							}
						} else {
							throw new Exception(respInfo.toString());
						}
					} else {
						throw new Exception(tmpSbMsg.toString());
					}
				} else {
					throw new Exception(tmpStrRet[1]);
				}
			} else {
				throw new Exception(tmpSign[1]);
			}
		} else {
			throw new Exception("登录失败");
		}
		return null;
	}

	/**
	 * 查询可撤回票据信息
	 * @param actNum
	 * @param billType
	 * @param billNo
	 * @param queryType
	 * @return
	 */
	protected XElement getBillInfoByCancel(String actNum, String billType, String billNo, String queryType)throws Exception {
		//赋值通用参数
		if("srv3030".equals(queryType)){
			serviceId ="srv3034_remindPayCancle";
		}else {
			serviceId = "srv3015_revokeCommonQuery";
		}
		XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
		//写入通用的头部节点
		writeCommonHeader(xmlWriter);
		if (!"".equals(bankFront.token)) {
			if("srv3030".equals(queryType)) {
				xmlWriter.writeElementString("functionId", "srv3034");
				xmlWriter.writeElementString("functionName", "提示付款撤销查询");
			}else {
				xmlWriter.writeElementString("functionId", "srv3015");
				xmlWriter.writeElementString("functionName", "撤回通用查询");
			}
			//请求报文体
			xmlWriter.writeStartElement("opReq");
			xmlWriter.writeElementString("serialNo", getQryTransID());//交易序列号
			xmlWriter.writeElementString("reqTime", Format.Date8Format.format(new Date()));//客户端请求时间
			xmlWriter.writeStartElement("ReqParam");
            if("srv3030".equals(queryType)) {
                xmlWriter.writeElementString("CXTJ", "1");//查询条件
            }else {
                xmlWriter.writeElementString("CXTJ", queryType);//查询条件
            }
			xmlWriter.writeElementString("KHHM", getBankConfig().getValueAsString("customerID"));//实际交易客户号
			xmlWriter.writeElementString("ZH", actNum);//出票账号
			xmlWriter.writeElementString("FZH", "");//子账号
			xmlWriter.writeElementString("PJHM", billNo);//票据号码
			xmlWriter.writeElementString("PJZL", getBillTypeToBank(billType));//票据类型
			xmlWriter.writeElementString("CPQR", "");//开始时间
			xmlWriter.writeElementString("CPZR", "");//结束时间
			xmlWriter.writeElementString("XSYH", "1");//页号
			xmlWriter.writeElementString("XSTS", getBankConfig().getValueAsString("pageSize"));//每页数量
			if("8".equals(queryType)||"9".equals(queryType)) {
				xmlWriter.writeElementString("DQQR","");//到期起日
				xmlWriter.writeElementString("DQZR","");//到期止日
			}
			xmlWriter.writeEndElement();
			xmlWriter.writeEndElement();
			String signXml = getDataSignData(xmlWriter);
			if (signnatrue(signXml) == true) {
				xmlWriter.writeElementString("signData", signature);//签名数据
				xmlWriter.writeEndDocument();
				String[] tmpStrRet = sendToBank(getDataSendBank(xmlWriter.toXmlString()));//发送银行
				if (tmpStrRet[0].length() == 0) {
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
					if (tmpBkReader != null) {
						String respCode = tmpBkReader.getFirstText("/NBCBEBankData/retCode");
						String respInfo = tmpBkReader.getFirstText("/NBCBEBankData/errorMsg");
						if (respCode != null && isActiveRetCode(respCode)) {
							int totalCount = Integer.parseInt(tmpBkReader.getFirstText("/NBCBEBankData/opRep/opResult/totalNumber"));
							if (totalCount!=1) {
								throw new Exception("返回的数据不唯一！");
							}
							if (tmpBkReader.read("/NBCBEBankData/opRep/opResult/list/row")) {
								return tmpBkReader.readedXElement;
							}
						} else {
							throw new Exception(respInfo);
						}
					} else {
						throw new Exception(tmpSbMsg.toString());
					}
				} else {
					throw new Exception(tmpStrRet[1]);
				}
			} else {
				throw new Exception(tmpSign[1]);
			}
		} else {
			throw new Exception("登录失败");
		}
		return null;
	}

	protected String getBillStatusByBillNo(String billNo) throws Exception{
        String billStatus="";
	    //赋值通用参数
        serviceId = "srv3027_singleBillInfoQuery";
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        //写入通用的头部节点
        writeCommonHeader(xmlWriter);
        if(!"".equals(bankFront.token)) {
            xmlWriter.writeElementString("functionId", "srv3027");
            xmlWriter.writeElementString("functionName", "单笔票据查询");
            //请求报文体
            xmlWriter.writeStartElement("opReq");
            xmlWriter.writeElementString("serialNo", getQryTransID());//交易序列号
            xmlWriter.writeElementString("reqTime", Format.Date8Format.format(new Date()));//客户端请求时间
            xmlWriter.writeStartElement("ReqParam");
            xmlWriter.writeElementString("PJHM", billNo);//票据号码
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            String signXml = getDataSignData(xmlWriter);
            if (signnatrue(signXml) == true) {
                xmlWriter.writeElementString("signData", signature);//签名数据
                xmlWriter.writeEndDocument();
                String[] tmpStrRet = sendToBank(getDataSendBank(xmlWriter.toXmlString()));//发送银行
                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String respCodes = tmpBkReader.getFirstText("/NBCBEBankData/retCode");
                        if (respCodes != null && isActiveRetCode(respCodes)) {
                            while(tmpBkReader.read("/NBCBEBankData/opRep/opResult")){
                                billStatus= tmpBkReader.readedXElement.getSingleTextNotNull("PJZT");//票据状态
                            }
                        }
                    }
                }
            }
        }
        return billStatus;
    }
}
